package com.server.db;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.server.background.data.Account;
import com.server.background.data.App;
import com.server.background.data.AppRanklist;
import com.server.background.data.AppSwitch;
import com.server.background.data.RankData;
import com.server.background.data.RankTableData;
import com.server.tools.AppData;
import com.server.tools.JsonUtil;
import com.server.tools.TimeUtils;
import com.server.tools.Tools;

public class DataBaseManager {
	private static final Logger logger = LoggerFactory.getLogger(DataBaseManager.class);
	
	public static DataBaseManager instance;
	public static DataBaseManager GetInstance(){
		if(instance == null){
			instance = new DataBaseManager();
		}
		return instance;
	}
	
	public void InitDBManager(){
		try {
			if(QueryData.GetInstance().QueryTestTableData()) {
				logger.info("数据库初始化成功!");
			}else {
				logger.info("数据库初始化失败!");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取管理员数据
	 * @param uname
	 * @param password
	 * @return
	 * @throws SQLException
	 */
	public Account GetAccountData(String uname,String password) {
		Account account = new Account();
		try {
			account = QueryData.GetInstance().GetAccountData(uname, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return account;
	}
	
	/**
	 * 检测帐号是否存在
	 */
	public int JudgeAccountExisted(String uname) {
		int status = 0;
		try {
			if(QueryData.GetInstance().JudgeAccountExisted(uname)) {
				status = 1;
			}
		} catch (SQLException e) {
			e.printStackTrace();
			status = 2;
		}
		return status;
	}
	
	/**
	 * 添加管理员
	 * @param uname
	 * @param password
	 * @param power
	 * @return
	 */
	public boolean AddAccount(String uname, String password, int power) {
		boolean isSuccess = false;
		try {
			isSuccess = InsertData.GetInstance().AddAccount(uname, password, power);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return isSuccess;
	}
	
	/**
	 * 获取管理员列表
	 * @return
	 */
	public String GetAccountList() {
		List<Account> accounts = new ArrayList<Account>();
		String json = "";
		try {
			accounts = QueryData.GetInstance().GetAccountList();
			if(accounts.size() > 0) {
				json = JsonUtil.ObjectToJsonString(accounts);
			}
		} catch (SQLException e) {
			json = null;
			e.printStackTrace();
		}
		return json;
	}
	
	/**
	 * 获取用户密码
	 * @param uname
	 * @return
	 * @throws SQLException
	 */
	public String GetAccountPassword(String uname){
		String	pas = null;
		
		try {
			pas = QueryData.GetInstance().GetAccountPassword(uname);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return pas;
	}
	
	/**
	 * 修改管理员密码
	 * @param uname
	 * @param password
	 * @return
	 */
	public boolean ChangeAccountPassword(String uname, String password) {
		boolean isSuccess = false;
		try {
			isSuccess = UpdateData.GetInstance().ChangeAccountPassword(uname, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return isSuccess;
	}
	
	/**
	 * 删除管理员
	 * @param uid
	 * @return
	 */
	public boolean DeleteAccount(long uid) {
		boolean isSuccess = false;
		try {
			isSuccess = DeleteData.GetInstance().DeleteAccount(uid);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return isSuccess;
	}
	
	/**
	 * 添加App
	 * @param appname
	 * @return
	 */
	public boolean AddApp(String appname) {
		boolean isSuccess = false;
		for (App value : AppData.appMap.values()) {
			if(value.appname.equals(appname)) {
				return false;
			}
		}
		try {
			String appkey = Tools.getNonceStr(16);
			long time = System.currentTimeMillis();
			long appid = time/1000 - 1537005200L;
			isSuccess = InsertData.GetInstance().AddApp(appid,appname, appkey);
			if(isSuccess) {
				App app = new App();
				app.appid = appid;
				app.appname = appname;
				app.appkey = appkey;
				app.createtime = TimeUtils.stampToDate(time);
				app.wx_appid = "--";
				app.wx_secret = "--";
				AppData.appMap.put(appid, app);
				if(InsertData.GetInstance().AddAppSwitch(appid,appname)) {
					AppSwitch as = new AppSwitch();
					as.appid = appid;
					as.appname = appname;
					as.switch_1 = 1;
					as.switch_2 = 1;
					as.switch_3 = 1;
					as.switch_4 = 1;
					as.switch_5 = 1;
					AppData.appSwitchMap.put(appid, as);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return isSuccess;
	}
	
	/**
	 * 获取App列表
	 * @return
	 */
	public String GetAppList() {
		return AppData.GetAppList();
	}
	
	/**
	 * 获取拥有权限的App资源列表
	 * @return
	 */
	public String GetAppResList(int uid) {
		List<App> app_list = new ArrayList<App>();
		List<Long> power_list = new ArrayList<Long>();
		String json = "";
		try {
			power_list = QueryData.GetInstance().GetPowerList(uid);
			if(power_list.size() > 0) {
				app_list = AppData.GetPowerAppList(power_list);
			}
			if(app_list.size() > 0) {
				json = JsonUtil.ObjectToJsonString(app_list);
			}
		} catch (SQLException e) {
			json = null;
			e.printStackTrace();
		}
		return json;
	}
	
	/**
	 * 添加App权限
	 * @param appname
	 * @return
	 */
	public String AddAppPower(String uname, long appid) {
		String failedMsg = null;
		try {
			if(QueryData.GetInstance().JudgeAccountExisted(uname)) {
				if(AppData.appMap.containsKey(appid)) {
					List<Long> power = QueryData.GetInstance().GetPowerList(uname);
					int index = power.indexOf(appid);
					if(index == -1) {
						power.add(appid);
					}
					UpdateData.GetInstance().ChangeAccountPower(uname, JsonUtil.ObjectToJsonString(power));
				}else {
					failedMsg = "该应用不存在!";
				}
			}else {
				failedMsg = "该管理员不存在!";
			}
		} catch (SQLException e) {
			e.printStackTrace();
			failedMsg = "查询数据库时发生异常!";
		}
		return failedMsg;
	}
	
	/**
	 * 删除App权限
	 * @param appname
	 * @return
	 */
	public String DelAppPower(String uname, long appid) {
		String failedMsg = null;
		try {
			if(QueryData.GetInstance().JudgeAccountExisted(uname)) {
				if(AppData.appMap.containsKey(appid)) {
					List<Long> power = QueryData.GetInstance().GetPowerList(uname);
					int index = power.indexOf(appid);
					if(index != -1) {
						power.remove(index);
					}
					UpdateData.GetInstance().ChangeAccountPower(uname, JsonUtil.ObjectToJsonString(power));
				}else {
					failedMsg = "该应用不存在!";
				}
			}else {
				failedMsg = "该管理员不存在!";
			}
		} catch (SQLException e) {
			e.printStackTrace();
			failedMsg = "查询数据库时发生异常!";
		}
		return failedMsg;
	}
	
	
	/**
	 * 修改应用的微信id
	 * @param wx_appid
	 * @param appid
	 * @return
	 */
	public String ChangeWxAppid(String wx_appid,long appid) {
		String failMsg = null;
		try {
			if(AppData.appMap.containsKey(appid)) {
				if(!UpdateData.GetInstance().ChangeAppWxId(wx_appid, appid)) {
					failMsg = "修改wx_appid失败!";
				}else {
					AppData.appMap.get(appid).wx_appid = wx_appid;
				}
			}else {
				failMsg = "该应用不存在!";
			}
		}catch (SQLException e) {
			e.printStackTrace();
			failMsg = "操作数据库时发生异常!";
		}
		
		return failMsg;
	}
	
	/**
	 * 修改应用的微信id
	 * @param wx_appid
	 * @param appid
	 * @return
	 */
	public String ChangeWxSecret(String wx_secret,long appid) {
		String failMsg = null;
		try {
			if(AppData.appMap.containsKey(appid)) {
				if(!UpdateData.GetInstance().ChangeAppWxSecret(wx_secret, appid)) {
					failMsg = "修改wx_secret失败!";
				}else {
					AppData.appMap.get(appid).wx_secret = wx_secret;
				}
			}else {
				failMsg = "该应用不存在!";
			}
		}catch (SQLException e) {
			e.printStackTrace();
			failMsg = "操作数据库时发生异常!";
		}
		
		return failMsg;
	}
	
	/**
	 * 初始化app开关
	 */
	public void InitAppSwitchMap() {
		try {
			QueryData.GetInstance().GetAppSwitch();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 初始化排行榜表单
	 */
	public void InitRanklistTable() {
		try {
			QueryData.GetInstance().GetRanklist();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 初始化app字典
	 */
	public void InitAppMap() {
		try {
			QueryData.GetInstance().GetAppMap();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取拥有权限的App开关列表
	 * @return
	 */
	public String GetAppSwitchList(int uid) {
		List<Long> power_list = new ArrayList<Long>();
		String json = "";
		try {
			power_list = QueryData.GetInstance().GetPowerList(uid);
			if(power_list.size() > 0) {
				json = AppData.SwitchToArray(power_list);
			}
		} catch (SQLException e) {
			json = null;
			e.printStackTrace();
		}
		return json;
	}
	
	/**
	 * 打开/关闭开关
	 * @param state
	 * @param game_switch
	 * @param appid
	 * @return
	 */
	public String UpdateSwitch(byte state, String game_switch,long appid) {
		String msg = null;
		try {
			UpdateData.GetInstance().UpdateSwitch(appid, state, game_switch);
			if(AppData.appSwitchMap.containsKey(appid)) {
				if(game_switch.equals("switch_1")) {
					AppData.appSwitchMap.get(appid).switch_1 = state;
				}else if(game_switch.equals("switch_2")){
					AppData.appSwitchMap.get(appid).switch_2 = state;
				}else if(game_switch.equals("switch_3")){
					AppData.appSwitchMap.get(appid).switch_3 = state;
				}else if(game_switch.equals("switch_4")){
					AppData.appSwitchMap.get(appid).switch_4 = state;
				}else if(game_switch.equals("switch_5")){
					AppData.appSwitchMap.get(appid).switch_5 = state;
				}
			}else {
				msg = "应用不存在!";
			}
		} catch (SQLException e) {
			e.printStackTrace();
			msg = "更新开关失败!";
		}
		return msg;
	}
	
	/**
	 * 获取玩家uid
	 * @param unionid
	 * @return
	 */
	public long GetUID(String unionid,long appid) {
		long uid = -4;
		try {
			uid = QueryData.GetInstance().GetUID(appid,unionid);
			if(uid <= 0) {
				uid = InsertData.GetInstance().InsertNewPlayer(appid,unionid);
				UpdateData.GetInstance().UpdateAppRegisterCount(appid);
			}else {
				UpdateData.GetInstance().UpdateAppGameCount(appid);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return uid;
	}
	
	/**
	 * 保存数据
	 * @param unionid
	 * @return
	 */
	public int SaveData(long uid,long appid, String key,String value) {
		int state = -4;
		try {
			if(QueryData.GetInstance().JudgeDataExisted(uid, appid, key)) {
				state = UpdateData.GetInstance().UpdateGameData(uid, appid, key, value);
			}else {
				state = InsertData.GetInstance().InsertGameData(uid, appid, key, value);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return state;
	}
	
	/**
	 * 获取数据
	 * @param unionid
	 * @return
	 */
	public String GetData(long uid,long appid, String key) {
		String data = null;
		try {
			data = QueryData.GetInstance().GetData(uid, appid, key);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return data;
	}
	
	/**
	 * 添加新的排行榜
	 * @param unionid
	 * @return
	 */
	public String AddRankList(long appid,String tablename, int resettime) {
		String data = null;
		try {
			int state = InsertData.GetInstance().CreateRankListTable(tablename);
			if(state == 1) {
				state = InsertData.GetInstance().AddRankList(appid, AppData.appMap.get(appid).appname,tablename ,resettime);
				if(state == 0) {
					data = "保存到已有排行榜表单时失败!";
				}else {
					RankTableData rtd = new RankTableData();
					rtd.rkid = state;
					rtd.appid = appid;
					rtd.appname = AppData.appMap.get(appid).appname;
					rtd.rkname = tablename;
					rtd.reset_time = resettime;
					rtd.create_time = TimeUtils.stampToDate(System.currentTimeMillis());
					AppData.rankTableMap.put(rtd.rkid, rtd);
					AppData.rankDataMap.put(rtd.rkid, new ArrayList<RankData>());
				}
			}else if(state == -3){
				data = "创建表格时失败!";
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return data;
	}
	
	/**
	 * 刷新排行榜
	 * @param rkid
	 * @param rkname
	 */
	public void RefreshRanklist(String rkname, List<RankData> r_list) {
		UpdateData.GetInstance().SaveRankList(rkname, r_list);
	}
	
	/**
	 * 刷新排行榜
	 * @param rkid
	 * @param rkname
	 */
	public void GetRanklist(int rkid, String rkname) {
		try {
			QueryData.GetInstance().RefreshRanklist(rkid, rkname);
		} catch (SQLException e) {
			System.err.println("刷新" + rkname + "排行榜失败!");
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取应用注册榜单
	 * @param rkid
	 * @param rkname
	 */
	public List<AppRanklist> GetAppRegisterRankList() {
		try {
			return QueryData.GetInstance().GetRegisterRank();
		} catch (SQLException e) {
			return null;
		}
	}
	
	/**
	 * 获取应用启动榜单
	 * @param rkid
	 * @param rkname
	 */
	public List<AppRanklist> GetAppGameRankList() {
		try {
			return QueryData.GetInstance().GetGameRank();
		} catch (SQLException e) {
			return null;
		}
	}
	/**
	 * 放入排行榜数据
	 * @param rkname
	 * @param uid
	 * @param appid
	 * @param uname
	 * @param uhead
	 * @param value
	 * @param info
	 * @return
	 */
	public int PutRankData(String rkname,long uid,String uname,String uhead,int value, String info) {
		try {
			if("".equals(uhead)) {
				return UpdateData.GetInstance().PutRankData(rkname, uid, uname, value, info);
			}else {
				return UpdateData.GetInstance().PutRankData(rkname, uid, uname, uhead, value, info);
			}
		} catch (SQLException e) {
			return -3;
		}
	}
	
	/**
	 * 登录统计
	 * @param appid
	 * @param type 0-新增用户 1-用户登录
	 * @return
	 */
	public int AppLoginStatis(long appid, int type) {
		int state = 0;
		try {
			if(type == 0) {
				state = UpdateData.GetInstance().UpdateAppRegisterCount(appid);
			}else if(type == 1) {
				state = UpdateData.GetInstance().UpdateAppGameCount(appid);
			}
		} catch (Exception e) {
			state = -3;
		}
		return state;
	}
	
	/**
	 * 检测礼包码
	 * @param redeem 礼包码
	 * @return 1：礼包码可以使用 0：礼包码已被使用 -1：错误
	 */
	public int JudgeRedeemCode(String redeem) {
		int state =0;
		try {
			state = QueryData.GetInstance().JudgeRedeem(redeem);
		}catch(Exception e) {
			state = -1;
		}
		return state;
	}
	
	/**
	 * 使用礼包码
	 * @param redeem 礼包码
	 * @return 1：礼包码可以使用 0：礼包码已被使用 -1：错误
	 */
	public void UseRedeemCode(String redeem) {
		if(JudgeRedeemCode(redeem) == 1) {
			try {
				InsertData.GetInstance().UseRedeemCode(redeem);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 检测名字是否重复
	 * @param pname
	 * @return
	 */
	public boolean JudgeName(String pname) {
		try {
			return QueryData.GetInstance().JudgeName(pname);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return true;
	}
	
	/**
	 * 插入已使用的名字
	 * @param pname
	 * @return
	 */
	public boolean AddName(String pname) {
		try {
			if(JudgeName(pname)) {
				return false;
			}else {
				InsertData.GetInstance().AddName(pname);
				return true;
			}
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 保存排行榜到服务器
	 * @param pname
	 * @return
	 */
	public void SaveRankList(String tb, List<RankData> r_list) {
		UpdateData.GetInstance().SaveRankList(tb, r_list);
	}
	
	/**
	 * 判断uid是否绑定
	 * @param pname
	 * @return 
	 * @return
	 */
	public boolean JudgeUidBind(long uid) {
		try {
			return !QueryData.GetInstance().JudgeUidBind(uid);
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 判断用户名是否重复
	 * @param pname
	 * @return 
	 * @return
	 */
	public boolean JudgeUsername(String username) {
		try {
			return !QueryData.GetInstance().JudgeUsername(username);
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 判断用户名是否重复
	 * @param pname
	 * @return 
	 * @return
	 */
	public boolean BindUsername(String username, String password, Long uid) {
		try {
			return InsertData.GetInstance().BindUsename(username, password, uid);
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 判断用户名是否重复
	 * @param pname
	 * @return 
	 * @return
	 */
	public Long LoginFromUsername(String username, String password) {
		try {
			return QueryData.GetInstance().LoginFromUsername(username, password);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return -1L;
	}

	public App GetApp(int appid) {
		try {
			return QueryData.GetInstance().GetAppData(appid);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public Map<Integer, com.server.background.data.Store> GetStoreData(){
		try {
			return QueryData.GetInstance().GetStoreMap();
		}catch(Exception e) {
			e.printStackTrace();
		}
		return new HashMap<Integer, com.server.background.data.Store>();
	}
}
